package com.yansl.http.autoconfig;

import java.lang.reflect.Method;
import java.util.Set;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import com.yansl.http.annotation.Http;
import com.yansl.http.annotation.URI;
import com.yansl.http.model.HttpRequest;
import com.yansl.http.proxy.HttpHandler;
import com.yansl.http.proxy.HttpProxy;
import com.yansl.http.utils.AnnotitionUtil;

import cn.hutool.core.util.ClassUtil;

/**
 * @description: Http扫描器
 * @author: eshengtai
 * @create: 2022-12-17 10:39
 */
public class HttpScan extends ClassPathBeanDefinitionScanner {

    public HttpScan(BeanDefinitionRegistry registry) {
        super(registry, true);
    }

    @Override
    protected void registerDefaultFilters() {
        super.addIncludeFilter(new AnnotationTypeFilter(Http.class));
    }

    @Override
    public Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
        for (BeanDefinitionHolder holder : beanDefinitions) {
            // 解析类信息
            String beanClassName = holder.getBeanDefinition().getBeanClassName();
            Class<Object> objectClass = ClassUtil.loadClass(beanClassName);

            // 采集请求信息
            gatherURL(objectClass);

            // 实例化对象
            GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
            definition.getConstructorArgumentValues().addGenericArgumentValue(holder.getBeanDefinition().getBeanClassName());
            definition.setBeanClass(HttpProxy.class);
            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
        return beanDefinitions;
    }

    /**
     * 采集HTTP请求信息
     * 
     * @param objectClass
     */
    private void gatherURL(Class<Object> objectClass) {
        for (Method method : objectClass.getMethods()) {
            String classMethodName = objectClass.getName() + "." + method.getName();

            // 普通请求
            if (AnnotitionUtil.isAnnotition(method, URI.class)) {
                URI annotation = method.getAnnotation(URI.class);

                HttpRequest hr = new HttpRequest();
                hr.setHttpIntercepterClass(annotation.intercepter());
                hr.setClassMethodName(classMethodName);
                hr.setHttpMethod(annotation.httpMethod());
                hr.setUrl(annotation.uri());
                hr.setReturnType(method.getReturnType());
                hr.setMethod(method);

                HttpHandler.setHttp(hr);
            }
        }
    }

    @Override
    public boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return true;
    }

}
